﻿using CCSSolderUI.Common.Event;
using CCSSolderUI.Models;
using HalconDotNet;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ViewROI;

namespace CCSSolderUI.ViewModels.Dialogs
{
    public class CameraCalibrationDialogViewModel : BindableBase, IDialogAware
    {
        #region 导航
        public string Title => "相机标定";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
            if (source != null)
            {
                GTSCard.Instance.AxisStop(GTSCard.Instance.X1, 1);
                GTSCard.Instance.AxisStop(GTSCard.Instance.Y1, 1);
                GTSCard.Instance.AxisStop(GTSCard.Instance.Z1, 1);
                source.Cancel();
            }
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            partNumber = parameters.GetValue<string>("PartNumber");
            LoadParam();
            Update(partNumber);
        }
        #endregion
        #region 变量
        string partNumber = "";
        Param param;
        IEventAggregator _eventAggregator;
        CancellationTokenSource source;
        #endregion
        #region 属性
        #region halcon
        private HImage cameraIamge0;
        public HImage CameraIamge0
        {
            get { return cameraIamge0; }
            set { SetProperty(ref cameraIamge0, value); }
        }
        private bool cameraRepaint0;
        public bool CameraRepaint0
        {
            get { return cameraRepaint0; }
            set { SetProperty(ref cameraRepaint0, value); }
        }
        private ObservableCollection<ROI> cameraROIList0 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList0
        {
            get { return cameraROIList0; }
            set { SetProperty(ref cameraROIList0, value); }
        }
        private HObject cameraAppendHObject0;
        public HObject CameraAppendHObject0
        {
            get { return cameraAppendHObject0; }
            set { SetProperty(ref cameraAppendHObject0, value); }
        }
        private HMsgEntry cameraAppendHMessage0;
        public HMsgEntry CameraAppendHMessage0
        {
            get { return cameraAppendHMessage0; }
            set { SetProperty(ref cameraAppendHMessage0, value); }
        }
        private Tuple<string, object> cameraGCStyle0;
        public Tuple<string, object> CameraGCStyle0
        {
            get { return cameraGCStyle0; }
            set { SetProperty(ref cameraGCStyle0, value); }
        }
        #endregion
        private AxisPoint cameraPoint;
        public AxisPoint CameraPoint
        {
            get { return cameraPoint; }
            set { SetProperty(ref cameraPoint, value); }
        }
        private AxisPoint actualPoint;
        public AxisPoint ActualPoint
        {
            get { return actualPoint; }
            set { SetProperty(ref actualPoint, value); }
        }
        private bool isAxisBusy = false;
        public bool IsAxisBusy
        {
            get { return isAxisBusy; }
            set { SetProperty(ref isAxisBusy, value); }
        }
        private bool isCalibMove = false;
        public bool IsCalibMove
        {
            get { return isCalibMove; }
            set { SetProperty(ref isCalibMove, value); }
        }
        #endregion
        #region 方法绑定
        private DelegateCommand<object> cameraOperateCommand;
        public DelegateCommand<object> CameraOperateCommand =>
            cameraOperateCommand ?? (cameraOperateCommand = new DelegateCommand<object>(ExecuteCameraOperateCommand));
        private DelegateCommand createShapModelCommand;
        public DelegateCommand CreateShapModelCommand =>
            createShapModelCommand ?? (createShapModelCommand = new DelegateCommand(ExecuteCreateShapModelCommand));
        private DelegateCommand findShapModelCommand;
        public DelegateCommand FindShapModelCommand =>
            findShapModelCommand ?? (findShapModelCommand = new DelegateCommand(ExecuteFindShapModelCommand));
        private DelegateCommand<object> getPositionCommand;
        public DelegateCommand<object> GetPositionCommand =>
            getPositionCommand ?? (getPositionCommand = new DelegateCommand<object>(ExecuteGetPositionCommand));
        private DelegateCommand<object> goPositionCommand;
        public DelegateCommand<object> GoPositionCommand =>
            goPositionCommand ?? (goPositionCommand = new DelegateCommand<object>(ExecuteGoPositionCommand));
        private DelegateCommand startCalibrationCommand;
        public DelegateCommand StartCalibrationCommand =>
            startCalibrationCommand ?? (startCalibrationCommand = new DelegateCommand(ExecuteStartCalibrationCommand));
        private DelegateCommand laserCenterCommand;
        public DelegateCommand LaserCenterCommand =>
            laserCenterCommand ?? (laserCenterCommand = new DelegateCommand(ExecuteLaserCenterCommand));

        void ExecuteLaserCenterCommand()
        {
            if (MessageBox.Show("确认标记\"激光中心\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                ROI roi = Global.MoveCameraCalibImageViewer.DrawROI(ROI.ROI_TYPE_CIRCLE);
                HRegion region = roi.getRegion();
                HTuple RegionRow;
                HOperatorSet.RegionFeatures(region, "row", out RegionRow);
                HTuple RegionColumn;
                HOperatorSet.RegionFeatures(region, "column", out RegionColumn);
                CameraAppendHObject0 = null;
                CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                CameraAppendHObject0 = region;
                HOperatorSet.WriteTuple(RegionRow, System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibCenterRow.tup"));
                HOperatorSet.WriteTuple(RegionColumn, System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibCenterColumn.tup"));
            }
        }
        void ExecuteStartCalibrationCommand()
        {
            if (MessageBox.Show("确认\"标定\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                if (IsCalibMove)
                {
                    IsAxisBusy = true;
                    source = new CancellationTokenSource();
                    CancellationToken token = source.Token;
                    Task.Run(() => CalibMove(token), token).ContinueWith(t => {
                        CalibCalc();
                        IsAxisBusy = false;
                    });
                }
                else
                {
                    CalibCalc();
                }
            }
        }
        async void ExecuteGoPositionCommand(object obj)
        {
            source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            GTSCard.Instance.ServoOn(GTSCard.Instance.X1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Y1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Z1);
            switch (obj.ToString())
            {
                case "CameraPoint":
                    if (MessageBox.Show($"确认运动到\"拍照点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoActionXYZ(token, CameraPoint), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "ActualPoint":
                    if (MessageBox.Show($"确认运动到\"打标点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoActionXYZ(token, ActualPoint), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                default:
                    break;
            }
        }
        void ExecuteGetPositionCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "CameraPoint":
                    if (MessageBox.Show($"确认设置\"拍照点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "CalibCamera");
                            if (point != null)
                            {
                                CameraPoint.X = point.X = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                                CameraPoint.Y = point.Y = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                                CameraPoint.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "CameraCalibrationDialog", Type = "Update", Content = null });
                    }
                    break;
                case "ActualPoint":
                    if (MessageBox.Show($"确认设置\"打标点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "CalibActual");
                            if (point != null)
                            {
                                ActualPoint.X = point.X = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                                ActualPoint.Y = point.Y = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                                ActualPoint.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "CameraCalibrationDialog", Type = "Update", Content = null });
                    }
                    break;
                default:
                    break;
            }
        }
        void ExecuteFindShapModelCommand()
        {
            try
            {
                HTuple ModelID;
                HOperatorSet.ReadShapeModel(System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibModelID1.shm"), out ModelID);
                HTuple Row, Column, Angle, Score;
                HOperatorSet.FindShapeModel(CameraIamge0, ModelID, new HTuple(-180).TupleRad(), new HTuple(360).TupleRad(), 0.5, 1, 0.5, "least_squares", new HTuple(5).TupleConcat(1), 0.75, out Row, out Column, out Angle, out Score);
                HOperatorSet.ClearShapeModel(ModelID);
                HTuple HomMat2D;
                HOperatorSet.HomMat2dIdentity(out HomMat2D);
                HOperatorSet.HomMat2dRotate(HomMat2D, Angle, 0, 0, out HomMat2D);
                HOperatorSet.HomMat2dTranslate(HomMat2D, Row, Column, out HomMat2D);
                HTuple hv_DxfStatus; HObject ModelContours;
                HOperatorSet.ReadContourXldDxf(out ModelContours, System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibModelContours1.dxf"), new HTuple(), new HTuple(), out hv_DxfStatus);
                HObject TransContours;
                HOperatorSet.AffineTransContourXld(ModelContours, out TransContours, HomMat2D);
                CameraAppendHObject0 = null;
                CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                CameraAppendHObject0 = TransContours;
                CameraAppendHMessage0 = null;
                CameraAppendHMessage0 = new HMsgEntry($"坐标:{Row.D:F1},{Column.D:F1},{Angle.TupleDeg().D:F1}° 分数:{Score.D:F1}", 100, 100);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteCreateShapModelCommand()
        {
            if (MessageBox.Show("确认创建\"9点标定\"模板吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    ROI roi = Global.MoveCameraCalibImageViewer.DrawROI(ROI.ROI_TYPE_REGION);
                    HRegion ModelRegion = roi.getRegion();
                    HObject TemplateImage;
                    HOperatorSet.ReduceDomain(CameraIamge0, ModelRegion, out TemplateImage);
                    HTuple ModelID;
                    HOperatorSet.CreateShapeModel(TemplateImage, 3, new HTuple(-180).TupleRad(), new HTuple(360).TupleRad(), new HTuple(1).TupleRad(), new HTuple("none").TupleConcat("no_pregeneration"), "use_polarity", new HTuple(30).TupleConcat(30).TupleConcat(0), 10, out ModelID);
                    HObject ModelContours;
                    HOperatorSet.GetShapeModelContours(out ModelContours, ModelID, 1);
                    HTuple ModelRegionArea, RefRow, RefColumn;
                    HOperatorSet.AreaCenter(ModelRegion, out ModelRegionArea, out RefRow, out RefColumn);
                    HTuple HomMat2D;
                    HOperatorSet.VectorAngleToRigid(0, 0, 0, RefRow, RefColumn, 0, out HomMat2D);
                    HObject TransContours;
                    HOperatorSet.AffineTransContourXld(ModelContours, out TransContours, HomMat2D);
                    CameraAppendHObject0 = null;
                    CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                    CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                    CameraAppendHObject0 = TransContours;
                    CameraAppendHMessage0 = null;
                    CameraAppendHMessage0 = new HMsgEntry($"坐标:{RefRow.D:F1},{RefColumn.D:F1}", 100, 100);
                    HOperatorSet.WriteShapeModel(ModelID, System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibModelID1.shm"));
                    HOperatorSet.ClearShapeModel(ModelID);
                    HOperatorSet.WriteContourXldDxf(ModelContours, System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibModelContours1.dxf"));

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        void ExecuteCameraOperateCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "拍照":
                    CameraIamge0 = Camera.Instance.GrabImage();
                    break;
                case "打开":
                    {
                        OpenFileDialog openFileDialog = new OpenFileDialog();
                        openFileDialog.Filter = "Image Files|*.png;*.bmp;*.jpg;*.tif";
                        if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            HObject image;
                            HOperatorSet.ReadImage(out image, openFileDialog.FileName);
                            CameraIamge0 = new HImage(image);
                        }
                    }
                    break;
                case "增强":
                    {
                        try
                        {
                            CameraIamge0 = new HImage(Camera.EnhancedImage(CameraIamge0));
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        #endregion
        #region 构造函数
        public CameraCalibrationDialogViewModel(IEventAggregator ea)
        {
            _eventAggregator = ea;
            _eventAggregator.GetEvent<MessagePrintEvent>().Subscribe(MessageReceived);
        }
        #endregion
        #region 功能函数
        private void MessageReceived(Common.Event.Message obj)
        {
            switch (obj.Type)
            {
                case "Select":
                    partNumber = obj.Content;
                    LoadParam();
                    Update(partNumber);
                    break;
                default:
                    break;
            }
        }
        void LoadParam()
        {
            try
            {
                //Json序列化，从文件读取
                string jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, partNumber, "Param.json"));
                param = JsonConvert.DeserializeObject<Param>(jsonString);

            }
            catch (Exception ex)
            {
                _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "CameraCalibrationDialogViewModel", Type = "Print", Content = ex.Message });
            }
        }
        void Update(string partnum)
        {
            using (var db = new DTContext(partnum))
            {
                var point = db.XYZPoints.FirstOrDefault(p => p.Name == "CalibCamera");
                if (point != null)
                {
                    CameraPoint = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }
                point = db.XYZPoints.FirstOrDefault(p => p.Name == "CalibActual");
                if (point != null)
                {
                    ActualPoint = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }
            }
        }
        private void GoActionXYZ(CancellationToken token, AxisPoint point)
        {
            int stepnum = 0;
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                switch (stepnum)
                {
                    case 0:
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.X1, point.X, param.X1JogSpeed);
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Y1, point.Y, param.Y1JogSpeed);
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Z1, point.Z, param.Z1JogSpeed);
                        stepnum = 1;
                        break;
                    case 1:
                        if (GTSCard.Instance.AxisCheckDone(GTSCard.Instance.X1) && GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Y1) && GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Z1))
                        {
                            return;
                        }
                        break;
                    default:
                        break;
                }
                System.Threading.Thread.Sleep(100);
            }
        }
        private void CalibMove(CancellationToken token)
        {
            try
            {
                double CalibMoveDist = 5;
                double[][] diffArray = new double[9][]
                                        { new double[]{ 0,0,0},
                                     new double[]{ CalibMoveDist * 1, 0,0} ,
                                     new double[]{ CalibMoveDist * 1, CalibMoveDist * 1,0},
                                     new double[]{ 0, CalibMoveDist * 1,0},
                                     new double[]{ CalibMoveDist * -1, CalibMoveDist * 1,0},
                                     new double[]{ CalibMoveDist * -1,0,0},
                                     new double[]{ CalibMoveDist * -1, CalibMoveDist * -1,0},
                                     new double[]{ 0, CalibMoveDist * -1,0},
                                     new double[]{ CalibMoveDist * 1, CalibMoveDist * -1,0}};
                //跑9点
                for (int i = 0; i < 9; i++)
                {
                    GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.X1, CameraPoint.X + diffArray[i][0], param.X1JogSpeed);
                    GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Y1, CameraPoint.Y + diffArray[i][1], param.X1JogSpeed);
                    while (!GTSCard.Instance.AxisCheckDone(GTSCard.Instance.X1) || !GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Y1))
                    {
                        System.Threading.Thread.Sleep(100);
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }
                    }
                    GTSCard.Instance.SetDo(2, 0);
                    System.Threading.Thread.Sleep(500);
                    CameraIamge0 = Camera.Instance.GrabImage();
                    GTSCard.Instance.SetDo(2, 1);
                    HOperatorSet.WriteImage(CameraIamge0, "jpeg", 0, System.IO.Path.Combine(System.Environment.CurrentDirectory, $"Calib\\MoveCameraImage\\{i + 1}.jpg"));
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void CalibCalc()
        {
            try
            {
                double CalibMoveDist = 5;
                double[][] diffArray = new double[9][]
                                        { new double[]{ 0,0,0},
                                     new double[]{ CalibMoveDist * 1, 0,0} ,
                                     new double[]{ CalibMoveDist * 1, CalibMoveDist * 1,0},
                                     new double[]{ 0, CalibMoveDist * 1,0},
                                     new double[]{ CalibMoveDist * -1, CalibMoveDist * 1,0},
                                     new double[]{ CalibMoveDist * -1,0,0},
                                     new double[]{ CalibMoveDist * -1, CalibMoveDist * -1,0},
                                     new double[]{ 0, CalibMoveDist * -1,0},
                                     new double[]{ CalibMoveDist * 1, CalibMoveDist * -1,0}};
                //计算9点标定
                double[][] Array1 = new double[9][];
                HTuple ModelID;
                HOperatorSet.ReadShapeModel(System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibModelID1.shm"), out ModelID);
                CameraAppendHMessage0 = null;
                for (int i = 0; i < 9; i++)
                {
                    try
                    {
                        HObject img;
                        HOperatorSet.ReadImage(out img, System.IO.Path.Combine(System.Environment.CurrentDirectory, $"Calib\\MoveCameraImage\\{i + 1}.jpg"));
                        HTuple Row, Column, Angle, Score;
                        HOperatorSet.FindShapeModel(img, ModelID, new HTuple(-180).TupleRad(), new HTuple(360).TupleRad(), 0.5, 1, 0.5, "least_squares", new HTuple(5).TupleConcat(1), 0.75, out Row, out Column, out Angle, out Score);
                        Array1[i] = new double[4] { Row.D, Column.D, CameraPoint.X + diffArray[i][0] * -1, CameraPoint.Y + diffArray[i][1] * -1 };
                        CameraAppendHMessage0 = new HMsgEntry($"{i + 1}", (int)Row.D, (int)Column.D, "green", "image", new HTuple().TupleConcat("box"), new HTuple().TupleConcat("false"));
                    }
                    catch (Exception ex)
                    {
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "CameraCalibrationDialogViewModel", Type = "Print", Content = ex.Message });
                        Array1[i] = new double[4] { 0, 0, CameraPoint.X + diffArray[i][0] * -1, CameraPoint.Y + diffArray[i][1] * -1 };
                    }
                }
                HOperatorSet.ClearShapeModel(ModelID);
                HTuple homMat2D;
                HOperatorSet.VectorToHomMat2d(new HTuple(Array1[0][0]).TupleConcat(Array1[1][0]).TupleConcat(Array1[2][0]).TupleConcat(Array1[3][0]).TupleConcat(Array1[4][0]).TupleConcat(Array1[5][0]).TupleConcat(Array1[6][0]).TupleConcat(Array1[7][0]).TupleConcat(Array1[8][0]),
                    new HTuple(Array1[0][1]).TupleConcat(Array1[1][1]).TupleConcat(Array1[2][1]).TupleConcat(Array1[3][1]).TupleConcat(Array1[4][1]).TupleConcat(Array1[5][1]).TupleConcat(Array1[6][1]).TupleConcat(Array1[7][1]).TupleConcat(Array1[8][1]),
                    new HTuple(Array1[0][2]).TupleConcat(Array1[1][2]).TupleConcat(Array1[2][2]).TupleConcat(Array1[3][2]).TupleConcat(Array1[4][2]).TupleConcat(Array1[5][2]).TupleConcat(Array1[6][2]).TupleConcat(Array1[7][2]).TupleConcat(Array1[8][2]),
                    new HTuple(Array1[0][3]).TupleConcat(Array1[1][3]).TupleConcat(Array1[2][3]).TupleConcat(Array1[3][3]).TupleConcat(Array1[4][3]).TupleConcat(Array1[5][3]).TupleConcat(Array1[6][3]).TupleConcat(Array1[7][3]).TupleConcat(Array1[8][3])
                    , out homMat2D);
                HTuple cencterRow, cencterColum;
                HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibCenterRow.tup"), out cencterRow);
                HOperatorSet.ReadTuple(System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibCenterColumn.tup"), out cencterColum);
                HTuple centerx, centery;
                HOperatorSet.AffineTransPoint2d(homMat2D, cencterRow, cencterColum, out centerx, out centery);

                double deltax = ActualPoint.X - centerx.D;
                double deltay = ActualPoint.Y - centery.D;

                HOperatorSet.VectorToHomMat2d(new HTuple(Array1[0][0]).TupleConcat(Array1[1][0]).TupleConcat(Array1[2][0]).TupleConcat(Array1[3][0]).TupleConcat(Array1[4][0]).TupleConcat(Array1[5][0]).TupleConcat(Array1[6][0]).TupleConcat(Array1[7][0]).TupleConcat(Array1[8][0]),
                new HTuple(Array1[0][1]).TupleConcat(Array1[1][1]).TupleConcat(Array1[2][1]).TupleConcat(Array1[3][1]).TupleConcat(Array1[4][1]).TupleConcat(Array1[5][1]).TupleConcat(Array1[6][1]).TupleConcat(Array1[7][1]).TupleConcat(Array1[8][1]),
                new HTuple(Array1[0][2] + deltax).TupleConcat(Array1[1][2] + deltax).TupleConcat(Array1[2][2] + deltax).TupleConcat(Array1[3][2] + deltax).TupleConcat(Array1[4][2] + deltax).TupleConcat(Array1[5][2] + deltax).TupleConcat(Array1[6][2] + deltax).TupleConcat(Array1[7][2] + deltax).TupleConcat(Array1[8][2] + deltax),
                new HTuple(Array1[0][3] + deltay).TupleConcat(Array1[1][3] + deltay).TupleConcat(Array1[2][3] + deltay).TupleConcat(Array1[3][3] + deltay).TupleConcat(Array1[4][3] + deltay).TupleConcat(Array1[5][3] + deltay).TupleConcat(Array1[6][3] + deltay).TupleConcat(Array1[7][3] + deltay).TupleConcat(Array1[8][3] + deltay)
                , out homMat2D);

                HOperatorSet.WriteTuple(homMat2D, System.IO.Path.Combine(System.Environment.CurrentDirectory, "Calib\\MoveCameraCalibHomMat2D.tup"));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion
    }
}
